home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / MISC / TSTHFLT2 / TSTHUNIT.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1996-12-01  |  13.1 KB  |  419 lines

  1. {(s0p16h0s0b4099T}
  2. Unit TSTHunit;
  3.  
  4. Interface
  5. {
  6.   This program source is a Turbo Pascal 7.0 utility for TstHost 1.41 and
  7.   higher.
  8.   This program accesses TstHost for information about the status of the
  9.   program and the tasks. Extended data request will be done trough the
  10.   internally IQR service vector, normally 101, 65Hex. This vector
  11.   may be redefined with the command TstHost /V, that accept in input a
  12.   DECIMAL value. This program is tested with TstHost 1.43b.
  13.   Written by Reg, PE1PKD, BLOKKER in HOLLAND.
  14.   Packet address : PE1PKD @ PI8WFL.#NH1.NLD.EU
  15. }
  16.  
  17. Uses Dos, Strings;
  18.  
  19. Type
  20.   DateStr = String[22];
  21.   InfoRec = Record
  22.               Version        : String[5];
  23.               MaxChannel     : Integer;
  24.               DrvType        : Byte;
  25.               Port           : Byte;
  26.               Baudrate       : Word;
  27.               IntNo          : Integer;
  28.               TstHostCall    : String[10];
  29.               UListEnable    : Byte;
  30.               Wpath          : String[81];
  31.               Upath          : String[101];
  32.               HomeBBS        : String[10];
  33.               HomeAlias      : String[10];
  34.               ChStatus       : Integer;
  35.               SuppCall       : String[10];
  36.               UserCall       : String[10];
  37.               UIname         : String[13];
  38.               UILastConnTime : DateStr;
  39.               UILastMsgList  : DateStr;
  40.               UINbrConn      : LongInt;
  41.               UIThisConnTime : DateStr;
  42.               SysFlag        : Word;
  43.               ExtraInfo      : String[10];
  44.             End;
  45.             ChannelList      = Array[0..8] of InfoRec;
  46.  
  47. Var
  48.   ChannelData      : ChannelList;     {All record data off the channels}
  49.   TstHostPath      : String;          {Path where TSHOST.EXE is located}
  50.  
  51. Function UpcaseStr(Str : String) : String;
  52.  
  53. Procedure GetTstHostIRQVector(Var IRQNumber     : Byte;
  54.                               Var TstHostActive : Boolean);
  55.  
  56. Function GetTstHostPath : String;
  57.  
  58. Procedure GetChannelsInfo(IRQVector : Byte);
  59.  
  60. Implementation
  61.  
  62. Type
  63.   InfoTstHostRec = Record
  64.      (* This record is translated from the C layout from the manual into
  65.         Turbo Pascal 7.0 layout. The record names are exactly the same as
  66.         described in the manual.*)
  67.      (* THIS FIELDS ARE GLOBALS, NOT CHANNEL DEPANDANT.*)
  68.      (*=============================================== *)
  69.      THVH           : Byte;                  (*TstHost version, high value*)
  70.      THVL           : Byte;                  (*TstHost version, low value*)
  71.      MaxChannel     : Integer;               (*Number of channels available in TstHost*)
  72.      DrvType        : Byte;                  (*Driver type, 1 real host, 0 tfpcx, 2 drsi*)
  73.      Port           : Byte;                  (*If real host, com port*)
  74.      Baudrate       : Word;                  (*If real host, baudrate*)
  75.      IntNo          : Integer;               (*If tfpcx/r, irq vector used by driver*)
  76.      TstHostCall    : Array[0..9] of Char;   (*Callsign of the system, with ssid*)
  77.      UListEnable    : Byte;                  (*If not 0, unproto list is  active*)
  78.      Wpath          : Array[0..80] of Char;  (*TstHost WorkDir*)
  79.      Upath          : Array[0..100] of Char; (*TstHost UserDir, if more than one path*)
  80.                                              (*is defined, the multiple path are*)
  81.                                              (*separated by a space.*)
  82.      HomeBBS        : Array[0..9] of Char;   (*HomeBBS Callsign*)
  83.      HomeAlias      : Array[0..9] of Char;   (*HomeBBS alias call, null if undefined*)
  84.  
  85.      (* THIS FIELDS ARE CHANNEL DEPANDANT*)
  86.      (*====================================================*)
  87.      ChStatus       : Integer;               (*0 = channel is disconnected*)
  88.                                              (*1 = standard connection, i have connect*)
  89.                                              (*    another OM*)
  90.                                              (*2 = PMS connection, a remote user is*)
  91.                                              (*  = connected on my pms*)
  92.                                              (*3 = PMS connection, HomeBBS have connect*)
  93.                                              (*  = my pms to do forward.*)
  94.                                              (*4 = PMS connection, my pms have connect*)
  95.                                              (*    HomeBBS to do forward*)
  96.                                              (*5 = UNPROTO connection, i have connect*)
  97.                                              (*    HomeBBS to request unproto mail.*)
  98.      SuppCall       : Array[0..9] of Char;   (*If not null, extra callsign for the*)
  99.                                              (*channel (command AX PORT)*)
  100.      UserCall       : Array[0..9] of Char;   (*Call of the connected station, with ssid*)
  101.  
  102.      (* THIS FIELDS ARE VALID ONLY FOR USER THAT HAVE CONNECT*)
  103.      (* MY PMS, chstatus=2 o 3*)
  104.      (*=====================================================*)
  105.      UIname         : Array[0..12] of Char;  (*User name*)
  106.      UILastConnTime : LongInt;               (*In sec dated since 1970, last connection date*)
  107.      UILastMsgList  : LongInt;               (*In sec, last messaged listed date*)
  108.      UINbrConn      : LongInt;               (*Number of connection for this user*)
  109.      UIThisConnTime : LongInt;               (*In second, this date at connection*)
  110.      SysFlag        : Word;                  (*Actual SYS flag for the user*)
  111.    End;
  112.  
  113. Var
  114.   Point            : ^InfoTstHostRec; {Typed pointer}
  115.  
  116.  
  117. Function UpcaseStr;
  118.  
  119. (* This function upcase all characters in the line *)
  120.  
  121. Var
  122.   Counter : Byte;
  123.  
  124. Begin
  125.   For Counter := 1 To Length(Str) Do
  126.     Str[Counter] := Upcase(Str[Counter]);
  127.   UpcaseStr := Str;
  128. End;
  129.  
  130.  
  131. Function IntToStr(I : LongInt) : String;
  132.  
  133. (* This function convert an Integer type to a string format *)
  134.  
  135. Var
  136.   S : String[11];
  137.  
  138. Begin
  139.   Str(I, S);
  140.   While Length(S) < 2 Do S := '0' + S;
  141.   IntToStr := S;
  142. End;
  143.  
  144.  
  145. Function CallExpand(Call : String) : String;
  146.  
  147. (* This function make sure that the given String in maded 10 characters length *)
  148.  
  149. Begin
  150.   If Length(Call) > 0 then
  151.     While Length(Call) <= 10 do Call := Call + ' ';
  152.   CallExpand := Call;
  153. End;
  154.  
  155.  
  156. Function GetTstHostPath;
  157.  
  158. { This function is returning the path where TstHost.exe is located. }
  159.  
  160. Var
  161.   PathName     : PathStr;
  162.   DirName      : Dirstr;
  163.   ProgName     : NameStr;
  164.   ExtName      : ExtStr;
  165.   DirInfo      : SearchRec;
  166.   PGPos        : Byte;
  167.  
  168. Begin
  169.   PathName := Fexpand(ParamStr(0));
  170.   FSplit(PathName,DirName,ProgName,ExtName);
  171.   PGPos := Pos('PG',DirName);
  172.   If PGPos = 0 then GetTstHostPath := DirName
  173.     else GetTstHostPath := Copy(DirName,1,PGPos-1);
  174. End;
  175.  
  176.  
  177. Procedure GetTstHostIRQVector;
  178.  
  179. { Read the IRQ vector from file TstHost.IRQ. This file only exist
  180.   when TstHost is started. This procedure checks or file exist and
  181.   so if TstHost is started.}
  182.  
  183. Var
  184.   IRQString,
  185.   Line,
  186.   TstHostIRQName : String;
  187.   TstHostIRQRead : Text;
  188.   DirInfo        : SearchRec;
  189.   Code           : Integer;
  190.   IRQPos         : Byte;
  191.  
  192. Begin
  193.   (* First check or this program is called under TstHost operation! *)
  194.   TstHostActive := True;
  195.   TstHostIRQName := GetTstHostPath + 'TstHost.IRQ';
  196.  
  197.   FindFirst(TstHostIRQName,AnyFile,DirInfo);
  198.   If DosError > 0 then
  199.   Begin
  200.     TstHostActive := False;
  201.     Exit;
  202.   End;
  203.  
  204.   (* Get the IRQvector number from file TstHost.IRQ *)
  205.   Assign(TstHostIRQRead, TstHostIRQName);
  206.   {$I-}
  207.   Reset(TstHostIRQRead);
  208.   {SI+}
  209.   If IOResult <> 0 then
  210.   Begin
  211.     TstHostActive := False;
  212.     Exit;
  213.   End;
  214.  
  215.   Repeat
  216.     Readln(TstHostIRQRead,Line);
  217.     IRQPos := Pos('=',Line);
  218.     IRQString := Copy(Line,IRQPos+1,3);
  219.     Val(IRQString,IRQNumber,Code);
  220.     If (IRQPos = 0) or (Code <> 0) Then
  221.     Begin
  222.       TstHostActive := False;
  223.       Exit;
  224.     End;
  225.   Until Eof(TstHostIRQRead);
  226.  
  227.   Close(TstHostIRQRead);
  228. End;
  229.  
  230.  
  231. Function Convert_SecondsToDate(Start_Seconds : LongInt) : DateStr;
  232.  
  233. (* This function return a date calculated from seconds input since 1970 counted *)
  234. (* Also calculating the UTC difference getting the set variable "TZ" *)
  235.  
  236. Const
  237.   DaysInMonth : Array[1..12] of Byte =
  238.     (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  239.   DaysInMonth_LeapYear : Array[1..12] of Byte =
  240.     (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  241.   DaysInWeek : Array[0..6] of String[3] =
  242.     ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  243.   MonthStr : Array[1..12] of String[3] =
  244.     ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  245.  
  246.   Seconds_Day      = 86400;
  247.   Seconds_Year     = 86400 * 365;
  248.   Seconds_LeapYear = 86400 * 366;
  249.  
  250. Var
  251.   DaySeconds,
  252.   Seconds     : LongInt;
  253.   Min,
  254.   Hour,
  255.   Day,
  256.   Month,
  257.   Year        : Word;
  258.   Code,
  259.   UTCOffset   : Integer;
  260.   TZ          : String;
  261.  
  262. Begin
  263.  
  264.   Year := 1970;
  265.   Seconds := Start_Seconds;
  266.  
  267.   (* Correction for the UTC time *)
  268.   TZ := GetEnv('TZ');
  269.   UTCOffset := 4;
  270.   If TZ <> '' then
  271.   Begin
  272.     Val(Copy(TZ,4,2),UTCOffset,Code);
  273.     If Code <> 0 then UTCOffset := 4;
  274.   End;
  275.  
  276.   Seconds := Seconds - (UTCOffset * 3600);
  277.   DaySeconds := Seconds;
  278.  
  279.   While ((Year MOD 4) = 0) and (Seconds - (Seconds_LeapYear) > 0) or
  280.         ((Year MOD 4) > 0) and (Seconds - (Seconds_Year) > 0) do
  281.   Begin
  282.     If Year MOD 4 = 0 then
  283.     Begin
  284.       If Seconds - Seconds_LeapYear > 0 then
  285.       Begin
  286.         Inc(Year);
  287.         Seconds := Seconds - Seconds_LeapYear;
  288.       End;
  289.     End else
  290.     Begin
  291.       If Seconds - Seconds_Year > 0 then
  292.       Begin
  293.         Inc(Year);
  294.         Seconds := Seconds - Seconds_Year;
  295.       End;
  296.     End;
  297.   End;
  298.  
  299.   Month := 1;
  300.   If Year MOD 4 = 0 then
  301.   Begin
  302.     While Seconds - (DaysInMonth_LeapYear[Month] * Seconds_Day) > 0 do
  303.     Begin
  304.       Seconds := Seconds - (DaysInMonth_LeapYear[Month] * Seconds_Day);
  305.       Inc(Month);
  306.     End;
  307.   End Else
  308.   Begin
  309.     While Seconds - (DaysInMonth[Month] * Seconds_Day) > 0 do
  310.     Begin
  311.       Seconds := Seconds - (DaysInMonth[Month] * Seconds_Day);
  312.       Inc(Month);
  313.     End;
  314.   End;
  315.  
  316.   Day       := (Seconds DIV Seconds_Day) + 1;
  317.   Seconds   := Seconds MOD Seconds_Day;
  318.   Hour      := Seconds DIV 3600;
  319.   Seconds   := Seconds MOD 3600;
  320.   Min       := Seconds DIV 60;
  321.   Seconds   := Seconds MOD 60;
  322.  
  323.   Convert_SecondsToDate := DaysInWeek[((DaySeconds DIV Seconds_Day) + 4) MOD 7] +
  324.                            ' ' + IntToStr(Day) + '-' + MonthStr[Month] + '-' +
  325.                            Copy(IntToStr(Year),3,2) +' ' + IntToStr(Hour) + ':' +
  326.                            IntToStr(Min) + ':' + IntToStr(Seconds) ;
  327. End;
  328.  
  329.  
  330. Procedure GetPointerInfo(TstHostIRQ : Byte;  Channel : Byte);
  331.  
  332. { This procedure gets the information from the memory location.
  333.   WARNING : On page 8 of the TSHOST 1.43 manual is mensioned that
  334.   register AH is set to the specified channel to investigate. This must
  335.   be register AL! }
  336.  
  337. Var
  338.   Reg : Registers;
  339.  
  340. Begin
  341.   With Reg do
  342.   Begin
  343.     AL := Channel;
  344.     AH := 0;
  345.     Intr(TstHostIRQ, Reg);
  346.     If AH <> 0 Then {When returning AH must be 0}
  347.     Begin
  348.       Writeln('Can''t connect to TstHost.');
  349.       Halt(0);
  350.     End;
  351.     Point := Ptr(ES,BX);
  352.   End;
  353. End;
  354.  
  355.  
  356. Procedure GetChannelsInfo;
  357.  
  358. { Scans all channels and get the data }
  359.  
  360. Var
  361.   Channel     : Byte;
  362.  
  363. Begin
  364.   GetPointerInfo(IRQVector,0); {First scan the MONITOR channel}
  365.   For Channel := 0 to Point^.MaxChannel do { Scan the channels 1 to max.}
  366.   Begin
  367.     GetPointerInfo(IRQVector,Channel);
  368.     With ChannelData[Channel] do
  369.     Begin
  370.       Str(Point^.THVH,Version);
  371.       Version        := Version + '.' + IntToStr(Point^.THVL);
  372.       MaxChannel     := Point^.MaxChannel;
  373.       DrvType        := Point^.DrvType;
  374.       Port           := Point^.Port;
  375.       Baudrate       := Point^.BaudRate;
  376.       Intno          := Point^.IntNo;
  377.       TstHostCall    := CallExpand(StrPas(Point^.TstHostCall));
  378.       UListEnable    := Point^.UListEnable;
  379.       Wpath          := StrPas(Point^.WPath);
  380.       Upath          := StrPas(Point^.Upath);
  381.       HomeBbs        := CallExpand(StrPas(Point^.HomeBBS));
  382.       HomeAlias      := CallExpand(StrPas(Point^.HomeAlias));
  383.       Chstatus       := Point^.ChStatus;
  384.       SuppCall       := CallExpand(StrPas(Point^.SuppCall));
  385.       UserCall       := CallExpand(StrPas(Point^.UserCall));
  386.       If (ChStatus = 2) or (ChStatus = 3) then
  387.       Begin
  388.         UIname         := StrPas(Point^.UIName);
  389.         If Point^.UILastConnTime = 0 then UILastConnTime := '' else
  390.           UILastConnTime := Convert_SecondsToDate(Point^.UILastConnTime);
  391.         If Point^.UILastMsgList = 0 then UILastMsgList := '' else
  392.           UILastMsgList  := Convert_SecondsToDate(Point^.UILastMsgList);
  393.         UINbrConn      := Point^.UINbrConn;
  394.         If Point^.UIThisConnTime = 0 then UIThisConnTime := '' else
  395.           UIThisConnTime := Convert_SecondsToDate(Point^.UIThisConnTime);
  396.         SysFlag        := Point^.SysFlag;
  397.         ExtraInfo      := '';
  398.       End Else
  399.       Begin
  400.         UIname         := '';
  401.         UILastConnTime := '';
  402.         UILastMsgList  := '';
  403.         UINbrConn      := 0;
  404.         UIThisConnTime := '';
  405.         SysFlag        := 0;
  406.         ExtraInfo      := '';
  407.       End;
  408.     End;
  409.  
  410.   End;
  411. End;
  412.  
  413.  
  414. End. {unit}
  415.  
  416.  
  417.  
  418.  
  419.